package net.ib.mtalk.database.helper;

import java.util.ArrayList;
import java.util.Date;
import java.util.UUID;

import net.ib.mntalk.protocol.Common;
import net.ib.mntalk.protocol.Common.ControlMessage;
import net.ib.mntalk.protocol.Common.SystemMessage;
import net.ib.mntalk.protocol.Common.SystemMessageOption;
import net.ib.mntalk.protocol.Common.UUIDMsg;
import net.ib.mntalk.protocol.Common.UserMessage;
import net.ib.mntalk.protocol.Common.ViewInfo;
import net.ib.mntalk.protocol.Session.CreateViewReq;
import net.ib.mntalk.protocol.Session.GetViewsRes;
import net.ib.mntalk.protocol.client.Database.ReceiverList;
import net.ib.mtalk.R;
import net.ib.mtalk.constant.MTalkConstant;
import net.ib.mtalk.database.DatabaseContract.MessageTable;
import net.ib.mtalk.database.DatabaseContract.ViewTable;
import net.ib.mtalk.database.DatabaseContract.ViewTable.PushType;
import net.ib.mtalk.global.GlobalPreferences;
import net.ib.mtalk.network.task.GetMembersTask;
import net.ib.mtalk.util.GpbSupport;
import net.ib.mtalk.util.MTalkLogWriter;
import net.ib.mtalk.util.TimeAdapter;
import net.ib.mtalk.util.UUIDGen;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.util.Log;
import android.view.View;

import com.google.protobuf.micro.InvalidProtocolBufferMicroException;

public class InboxDatabaseHelper {
	
	public static final int ONE_VIEW_SELECT 	= 0x01;
	public static final int MULTI_VIEW_SELECT 	= 0x02;
	
	/** 생성 Create(Insert) **/
	/**
	 * ViewInfo 정보를 이용하여 View를 생성
	 * @param context
	 * @param viewInfo
	 */
	public static UUID insertView(Context context,
			ViewInfo viewInfo ) {
		return insertView(context, viewInfo, PushType.ON);
	}

	/**
	 * 서버로 부터 받은 View를 insert 한다.
	 * @param context
	 * @param getViewsRes
	 */
	public static void insertSyncView(Context context, GetViewsRes getViewsRes){
		ViewInfo viewInfo = new ViewInfo();
		for(int i = 0; i < getViewsRes.getViewCount(); i++){
			viewInfo = getViewsRes.getView(i);
			syncView(context, viewInfo);

			// NotiUUID를 설정해준다.
			if(getViewsRes.getView(i).hasLatestMessage()){
				GlobalPreferences.setLastViewChangedNotiUUID(getViewsRes.getView(i).getLatestMessage().getNotiUuid());
			}
		}
	}
	
	public static UUID syncView(Context context, ViewInfo viewInfo){
		if(!existCheckView(context, viewInfo)){
			return insertView(context, viewInfo);
		}else{
			return updateView(context, viewInfo);
		}
	}
	
	public static boolean existCheckView(Context context, ViewInfo viewInfo){
		ContentResolver cr = context.getContentResolver();
		String select = "(" + ViewTable.KEY_VIEW_UUID_MSB + "=? AND "
						+ ViewTable.KEY_VIEW_UUID_LSB + "=? )";
		String[] selectionArgs = new String[]{ String.valueOf(GpbSupport.msbOf(viewInfo.getViewUuid())), String.valueOf(GpbSupport.lsbOf(viewInfo.getViewUuid()))};
		Cursor cursor = cr.query(ViewTable.CONTENT_URI, new String[]{ViewTable.KEY_VIEW_ENABLE}, select, selectionArgs, null);
		int enable = ViewTable.EnableType.DISABLE.ordinal();
		if(cursor.moveToFirst()){
			enable = cursor.getInt(cursor.getColumnIndexOrThrow(ViewTable.KEY_VIEW_ENABLE));
		}
		cursor.close();
		boolean exist = (enable == ViewTable.EnableType.ENABLE.ordinal());
		return exist;
	}
	
	/**
	 * 서버로 부터 받은 View를 최초로 insert 하는 기본 메소드
	 * @param context
	 * @param viewInfo
	 * @param pushType
	 */
	public static UUID insertView(Context context,
			ViewInfo viewInfo,
			PushType pushType
			) {
		UUID clientViewUuid = UUID.randomUUID();
		ContentValues cv = new ContentValues();
		cv.put(ViewTable.KEY_CLIENT_VIEW_UUID_MSB, clientViewUuid.getMostSignificantBits());
		cv.put(ViewTable.KEY_CLIENT_VIEW_UUID_LSB, clientViewUuid.getLeastSignificantBits());
		if(viewInfo.hasViewUuid()){
			cv.put(ViewTable.KEY_VIEW_UUID_MSB, GpbSupport.msbOf(viewInfo.getViewUuid()));
			cv.put(ViewTable.KEY_VIEW_UUID_LSB, GpbSupport.lsbOf(viewInfo.getViewUuid()));
		}else{
			cv.put(ViewTable.KEY_VIEW_UUID_MSB, clientViewUuid.getMostSignificantBits());
			cv.put(ViewTable.KEY_VIEW_UUID_LSB, clientViewUuid.getLeastSignificantBits());
		}
		if(viewInfo.hasReceiverUuid()){
			cv.put(ViewTable.KEY_RECEIVER_UUID_MSB, GpbSupport.msbOf(viewInfo.getReceiverUuid()));
			cv.put(ViewTable.KEY_RECEIVER_UUID_LSB, GpbSupport.lsbOf(viewInfo.getReceiverUuid()));
		}
		cv.put(ViewTable.KEY_CHAT_TYPE, viewInfo.getType());
		cv.put(ViewTable.KEY_VIEW_UNREAD_COUNT, viewInfo.getUnreadCount());
		cv.put(ViewTable.KEY_VIEW_MEMBER_COUNT, viewInfo.getMemberCount()); // TODO 테스트해볼것
		
		if(viewInfo.hasTitle()){
			cv.put(ViewTable.KEY_TITLE, viewInfo.getTitle());
		} else {
			switch(viewInfo.getType()){
				case Common.ONE_TO_ONE:
					cv.put(ViewTable.KEY_TITLE, context.getString(R.string.inbox_chat_title));
					break;
				case Common.GROUP_CHAT:
					cv.put(ViewTable.KEY_TITLE, context.getString(R.string.inbox_group_chat_title));
					break;
				case Common.BROADCAST:
					cv.put(ViewTable.KEY_TITLE, context.getString(R.string.inbox_broadcase_title));
					break;
				default:
					cv.put(ViewTable.KEY_TITLE, context.getString(R.string.inbox_chat_title));
					break;
			}
		}
		if(viewInfo.hasLatestMessage()){
			if(viewInfo.getLatestMessage().getType()==Common.MSG_TYPE_USER_MSG){
				cv.put(ViewTable.KEY_SUB_TITLE, viewInfo.getLatestMessage().getUserMassage().getContent());
			}
			/**
			 *  시스템/컨트롤  메시지는 무시
			 */
//			else if(viewInfo.getLatestMessage().getType()==Common.MSG_TYPE_SYSTEM_MSG){
//				cv.put(ViewTable.KEY_SUB_TITLE, "시스템 메시지"); // TODO : 시스템 메시지일때 표시 기준
//			}else if(viewInfo.getLatestMessage().getType()==Common.MSG_TYPE_CONTROL_MSG){
//				cv.put(ViewTable.KEY_SUB_TITLE, "컨트롤 메시지"); // TODO : 컨트롤 메시지일대 표시 기준
//			}
			cv.put(ViewTable.KEY_MESSAGE_LAST_TIME, TimeAdapter.getMillisecondFromUUID(GpbSupport.makeUuid(viewInfo.getLatestMessage().getMsgUuid())));
		}else{
			cv.put(ViewTable.KEY_MESSAGE_LAST_TIME, System.currentTimeMillis());
		}
		
		if(viewInfo.hasPushAllowed()){
			cv.put(ViewTable.KEY_VIEW_PUSH_ONOFF, viewInfo.getPushAllowed());
		}else{
			if(pushType!=null) cv.put(ViewTable.KEY_VIEW_PUSH_ONOFF, pushType.ordinal());			
		}
		cv.put(ViewTable.KEY_VIEW_ENABLE, ViewTable.EnableType.ENABLE.ordinal());
		
		ContentResolver cr = context.getContentResolver();
		cr.insert(ViewTable.CONTENT_URI, cv);
		return clientViewUuid;
	}

	/**
	 * CreateViewReq로 서버에View가 만들어지면 CreateViewRes에서 받은 ViewUuid로 View를 만든다.
	 * @param context
	 * @param clientViewUuid dummyView 를 만든다.
	 */
	public static void createView(Context context, UUID clientViewUuid, CreateViewReq createViewReq) {
		ContentValues cv = new ContentValues();
		cv.put(ViewTable.KEY_CLIENT_VIEW_UUID_MSB, clientViewUuid.getMostSignificantBits());
		cv.put(ViewTable.KEY_CLIENT_VIEW_UUID_LSB, clientViewUuid.getLeastSignificantBits());
		cv.put(ViewTable.KEY_VIEW_UUID_MSB, clientViewUuid.getMostSignificantBits());
		cv.put(ViewTable.KEY_VIEW_UUID_LSB, clientViewUuid.getLeastSignificantBits());
		cv.put(ViewTable.KEY_MESSAGE_LAST_TIME, System.currentTimeMillis());
		cv.put(ViewTable.KEY_VIEW_ENABLE, ViewTable.EnableType.DISABLE.ordinal());
		
		ReceiverList receiverList = new ReceiverList();
		
		int chatType = createViewReq.getType();
		cv.put(ViewTable.KEY_CHAT_TYPE, chatType);

		int receiverCount = createViewReq.getReceiversCount();
		cv.put(ViewTable.KEY_VIEW_MEMBER_COUNT, receiverCount);
		
		for(int i = 0; i < receiverCount; i++){
			receiverList.addReceiver(createViewReq.getReceivers(i));
		}
		
		String receiverNameList = BuddyDatabaseHelper.getReceiverName(context, receiverList);
		
		switch(chatType){
			case Common.ONE_TO_ONE:
				cv.put(ViewTable.KEY_RECEIVER_UUID_MSB, GpbSupport.msbOf(createViewReq.getReceivers(0).getUserUuid()));
				cv.put(ViewTable.KEY_RECEIVER_UUID_LSB, GpbSupport.lsbOf(createViewReq.getReceivers(0).getUserUuid()));
				cv.put(ViewTable.KEY_VIEW_PUSH_ONOFF, PushType.ON.ordinal());
				cv.put(ViewTable.KEY_TITLE, receiverNameList);
				cv.put(ViewTable.KEY_SUB_TITLE, " ");
				break;
			case Common.GROUP_CHAT:
				cv.put(ViewTable.KEY_VIEW_PUSH_ONOFF, PushType.ON.ordinal());
				cv.put(ViewTable.KEY_TITLE, context.getString(R.string.inbox_group_chat_title));
				cv.put(ViewTable.KEY_SUB_TITLE, receiverNameList);
				break;
			case Common.BROADCAST:
				cv.put(ViewTable.KEY_VIEW_PUSH_ONOFF, PushType.ON.ordinal());
				cv.put(ViewTable.KEY_TITLE, context.getString(R.string.inbox_group_chat_title));
				cv.put(ViewTable.KEY_SUB_TITLE, receiverNameList);
				break;
			default:
				cv.put(ViewTable.KEY_VIEW_PUSH_ONOFF, PushType.ON.ordinal());
				cv.put(ViewTable.KEY_TITLE, context.getString(R.string.inbox_chat_title));
				cv.put(ViewTable.KEY_SUB_TITLE, " ");
				break;
		}
		
		cv.put(ViewTable.KEY_VIEW_UNREAD_COUNT, 0);
		cv.put(ViewTable.KEY_RECEIVER_LIST, receiverList.toByteArray());
		
		ContentResolver cr = context.getContentResolver();
		cr.insert(ViewTable.CONTENT_URI, cv);
	}
	
	
	
	
	
	
	/** 읽기 Read(Query) **/
	
	/**
	 * 뷰에 대한 대화 내용을 메일로 보낸다.
	 * @param context
	 * @param clientViewUuid
	 */
	public static void getHistoryMessageBackup(Context context, UUID clientViewUuid){
		
		UUIDMsg viewUuid = InboxDatabaseHelper.getViewUUID(context, clientViewUuid);
		String select = "(" + MessageTable.KEY_VIEW_UUID_MSB + "=? AND "
		+ MessageTable.KEY_VIEW_UUID_LSB + "=? )";
		String[] selectionArgs = new String[]{ String.valueOf(GpbSupport.msbOf(viewUuid)), String.valueOf(GpbSupport.lsbOf(viewUuid))}; 
		String sortOrder = MessageTable.KEY_MESSAGE_TIME + " COLLATE LOCALIZED ASC";
		ContentResolver cr = context.getContentResolver();
		Cursor messageCursor = cr.query(MessageTable.CONTENT_URI, 
				new String[]{ MessageTable.KEY_MESSAGE_OBJECT_TYPE, MessageTable.KEY_MESSAGE, 
					MessageTable.KEY_MESSAGE_TIME, MessageTable.KEY_FILE_URI }, 
				select,
				selectionArgs,
				sortOrder);
		
		StringBuilder chatHistory = new StringBuilder();
		String newline = "\n";
		
		long lastTime = 0L;
		ArrayList<Uri> uriList = new ArrayList<Uri>();

		while(messageCursor.moveToNext()){
			try {
				// 날짜 변경 확인
				long messageTime = messageCursor.getLong(messageCursor.getColumnIndexOrThrow(MessageTable.KEY_MESSAGE_TIME));
				switch(TimeAdapter.CompareTimeLong(lastTime, messageTime)){
					case TimeAdapter.DATE_CHANGED_NONE:
						break;
					case TimeAdapter.DATE_CHANGED_MONTH:
					case TimeAdapter.DATE_CHANGED_WEEK:
					case TimeAdapter.DATE_CHANGED_YEAR:
					case TimeAdapter.DATE_CHANGED_DAY_ONE:
					case TimeAdapter.DATE_CHANGED_DAY_TWO:
					case TimeAdapter.DATE_CHANGED_DAY_THREE:
					case TimeAdapter.DATE_CHANGED_DAY_FOUR:
					case TimeAdapter.DATE_CHANGED_DAY_FIVE:
					case TimeAdapter.DATE_CHANGED_DAY_SIX:
						chatHistory.append(TimeAdapter.Date2Str(new Date(messageTime), "dd. MMMM. yyyy")).append(newline);
						break;
					default:
						break;
				}
				
				
				if(messageCursor.getInt(messageCursor.getColumnIndexOrThrow(MessageTable.KEY_MESSAGE_OBJECT_TYPE))==Common.MSG_TYPE_USER_MSG){
					UserMessage um = UserMessage.parseFrom(messageCursor.getBlob(messageCursor.getColumnIndexOrThrow(MessageTable.KEY_MESSAGE)));
					if(um.getContentType() == Common.CONTENT_TYPE_PLAIN){
						// 이름 표시 
						chatHistory.append(um.getSenderName());
						// 시간 표시
						chatHistory.append("(").append(TimeAdapter.Date2Str(new Date(messageTime), "kk:mm")).append(") : ");
						// 내용 표시
						chatHistory.append(um.getContent()).append(newline);
					}else if(um.getContentType() == Common.CONTENT_TYPE_ATTACHMENT){
						// 작은 첨부파일(vCard/vCalendar/GeoTag/Gift)
						if(um.getAttachment().getMimeType() == MTalkConstant.MIME_TYPE_VCARD){
							chatHistory.append(context.getString(R.string.attachment_vcard_name))
							.append("_").append(um.getAttachment().getFileName());
						}else if(um.getAttachment().getMimeType() == MTalkConstant.MIME_TYPE_VCALENDAR){
							chatHistory.append(context.getString(R.string.attachment_vcalendar_name))
							.append("_").append(um.getAttachment().getFileName());
						}else if(um.getAttachment().getMimeType() == MTalkConstant.MIME_TYPE_GEOTAG){
							chatHistory.append(context.getString(R.string.attachment_geotag_name))
							.append("_").append(um.getAttachment().getFileName());
						}else if(um.getAttachment().getMimeType() == MTalkConstant.MIME_TYPE_GIFT){
							chatHistory.append(context.getString(R.string.attachment_gift_name))
							.append("_").append(um.getAttachment().getFileName());
						}else{
							chatHistory.append(context.getString(R.string.attachment_unknown))
							.append("_").append(um.getAttachment().getFileName());
						}
						chatHistory.append("(").append(TimeAdapter.Date2Str(new Date(messageTime), "kk:mm")).append(")")
						.append(newline);
					}else if(um.getContentType() == Common.CONTENT_TYPE_HTML){
						switch(um.getAttachFile().getFileType()){
							case Common.FT_PROFILE_IMG:
							case Common.FT_IMG:
								chatHistory.append(context.getString(R.string.attachment_image_name))
								.append("_").append(um.getAttachFile().getFileName());
								Log.d("ATOM", "uri : " + messageCursor.getString(messageCursor.getColumnIndexOrThrow(MessageTable.KEY_FILE_URI)));
								if(messageCursor.getString(messageCursor.getColumnIndexOrThrow(MessageTable.KEY_FILE_URI)) != null
									&& !messageCursor.getString(messageCursor.getColumnIndexOrThrow(MessageTable.KEY_FILE_URI)).equals("")){
										uriList.add(Uri.parse(messageCursor.getString(messageCursor.getColumnIndexOrThrow(MessageTable.KEY_FILE_URI))));
								}
								break;
							case Common.FT_VIDEO:
								chatHistory.append(context.getString(R.string.attachment_video_name))
								.append("_").append(um.getAttachFile().getFileName());
								break;
							case Common.FT_AUDIO:
								chatHistory.append(context.getString(R.string.attachment_audio_name))
								.append("_").append(um.getAttachFile().getFileName());
								break;
							default:
								chatHistory.append(context.getString(R.string.attachment_image_name))
								.append("_").append(um.getAttachFile().getFileName());
								break;
						}
						chatHistory.append("(").append(TimeAdapter.Date2Str(new Date(messageTime), "kk:mm")).append(")")
						.append(newline);
					}else{
						chatHistory.append("(").append(TimeAdapter.Date2Str(new Date(messageTime), "kk:mm")).append(") : ")
						.append("?").append(newline);
					}
				} else if(messageCursor.getInt(messageCursor.getColumnIndexOrThrow(MessageTable.KEY_MESSAGE_OBJECT_TYPE))==Common.MSG_TYPE_SYSTEM_MSG){
					SystemMessage sm = SystemMessage.parseFrom(messageCursor.getBlob(messageCursor.getColumnIndexOrThrow(MessageTable.KEY_MESSAGE)));
					String param1List = " ";
					String param2List = " ";
					String param3List = " ";
					for(SystemMessageOption smo : sm.getSystemMessageOptionList()){
						for(int i = 0; i < smo.getParam1Count(); i++){
							if(i == 0){
								param1List = smo.getParam1(i);
							}else{
								param1List = param1List + ", " + smo.getParam1(i);
							}
						}
						for(int i = 0; i < smo.getParam2Count(); i++){
							if(i == 0){
								param2List = smo.getParam2(i);
							}else{
								param2List = param2List + ", " + smo.getParam2(i);
							}
						}
						for(int i = 0; i < smo.getParam3Count(); i++){
							if(i == 0){
								param3List = smo.getParam3(i);
							}else{
								param3List = param3List + ", " + smo.getParam3(i);
							}
						}
					}
					String smContent = " ";
					
					chatHistory.append("(").append(TimeAdapter.Date2Str(new Date(messageTime), "kk:mm")).append(") : ");
					if(sm.getType() == Common.SYS_MSG_TYPE_MEMBER_ADDED){
						smContent = context.getString(R.string.chat_system_message_add_format);
						smContent = smContent.replaceAll("#S", param1List);
						smContent = smContent.replaceAll("#R", param2List);
					}else if(sm.getType() == Common.SYS_MSG_TYPE_MEMBER_REMOVED){
						smContent = context.getString(R.string.chat_system_message_remove_format);
						smContent = smContent.replaceAll("#L", param1List);						
					}else{
						smContent = "SystemMessage";
					}
					chatHistory.append(smContent).append(newline);
				} else if(messageCursor.getInt(messageCursor.getColumnIndexOrThrow(MessageTable.KEY_MESSAGE_OBJECT_TYPE))==Common.MSG_TYPE_CONTROL_MSG){
					ControlMessage cm = ControlMessage.parseFrom(messageCursor.getBlob(messageCursor.getColumnIndexOrThrow(MessageTable.KEY_MESSAGE)));
				}
				
				lastTime = messageTime;
			} catch (InvalidProtocolBufferMicroException e) {
				MTalkLogWriter.e(e);
			}
		}
		messageCursor.close();
		
		// 제목을 만들어 주자~!
		String subject = "[M Talk] ";
		Cursor viewCursor = cr.query(ViewTable.CONTENT_URI, new String[]{ViewTable.KEY_TITLE}, select, selectionArgs, null);
		if(viewCursor.moveToFirst()){
			subject = subject + viewCursor.getString(viewCursor.getColumnIndexOrThrow(ViewTable.KEY_TITLE));
		}
		
		Intent sendIntent = new Intent(Intent.ACTION_SEND_MULTIPLE);
		sendIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
		sendIntent.setType("message/rfc822");
		
		if(uriList.size() > 0){
			sendIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uriList);
			sendIntent.setType("image/jpg");
		}
		
		sendIntent.putExtra(Intent.EXTRA_TEXT, chatHistory.toString());
		context.startActivity(Intent.createChooser(sendIntent, "Send email"));
	}
	
	/**
	 * viewUuid 를 가지고 clientUUID 를 찾는다.
	 * @param context
	 * @param viewUuidMsb
	 * @param viewUuidLsb
	 * @return
	 */
	public static UUID getClientUUID(Context context, long viewUuidMsb, long viewUuidLsb){
		String[] projection = new String[]{ ViewTable.KEY_CLIENT_VIEW_UUID_MSB, ViewTable.KEY_CLIENT_VIEW_UUID_LSB };
		String select = "(" + ViewTable.KEY_VIEW_UUID_MSB + "=? AND "
		+ ViewTable.KEY_VIEW_UUID_LSB + "=?)";
		String[] selectionArgs = new String[]{ String.valueOf(viewUuidMsb), String.valueOf(viewUuidLsb)}; 
		ContentResolver cr = context.getContentResolver();
		Cursor viewCursor = cr.query(ViewTable.CONTENT_URI, 
				projection, 
				select,
				selectionArgs,
				null);
		
		UUID clientViewUuid = UUID.randomUUID();
		if(viewCursor.moveToFirst()){
			long clientViewUuidMsb = viewCursor.getLong(viewCursor.getColumnIndexOrThrow(ViewTable.KEY_CLIENT_VIEW_UUID_MSB));
			long clientViewUuidLsb = viewCursor.getLong(viewCursor.getColumnIndexOrThrow(ViewTable.KEY_CLIENT_VIEW_UUID_LSB));
			clientViewUuid = new UUID(clientViewUuidMsb, clientViewUuidLsb);
		}
		viewCursor.close();
		return clientViewUuid;
	}

	/**
	 * viewUuid 를 가지고 clientUUID 를 찾는다.
	 * @param context
	 * @param viewUuid
	 * @return
	 */
	public static UUID getClientUUID(Context context, UUIDMsg viewUuid){
		return getClientUUID(context, GpbSupport.msbOf(viewUuid), GpbSupport.lsbOf(viewUuid));
	}
	
	/**
	 * clientUuid 를 가지고 viewUuid 를 찾는다.
	 * @param context
	 * @param clientViewUuidMsb
	 * @param clientViewUuidLsb
	 * @return
	 */
	public static UUIDMsg getViewUUID(Context context, long clientViewUuidMsb, long clientViewUuidLsb){
		String[] projection = new String[]{ ViewTable.KEY_VIEW_UUID_MSB, ViewTable.KEY_VIEW_UUID_LSB };
		String select = "(" + ViewTable.KEY_CLIENT_VIEW_UUID_MSB + "=? AND "
		+ ViewTable.KEY_CLIENT_VIEW_UUID_LSB + "=?)";
		String[] selectionArgs = new String[]{ String.valueOf(clientViewUuidMsb), String.valueOf(clientViewUuidLsb)}; 
		ContentResolver cr = context.getContentResolver();
		Cursor viewCursor = cr.query(ViewTable.CONTENT_URI, 
				projection, 
				select,
				selectionArgs,
				null);
		UUIDMsg viewUuid = null; // TODO : 확인
		if(viewCursor.moveToFirst()){
			long viewUuidMsb = viewCursor.getLong(viewCursor.getColumnIndexOrThrow(ViewTable.KEY_VIEW_UUID_MSB));
			long viewUuidLsb = viewCursor.getLong(viewCursor.getColumnIndexOrThrow(ViewTable.KEY_VIEW_UUID_LSB));
			viewUuid = GpbSupport.makeUuidMsg(viewUuidMsb, viewUuidLsb);
		}
		viewCursor.close();
		return viewUuid;
	}

	// clientUuid 를 가지고 viewUuid 를 찾는다.
	public static UUIDMsg getViewUUID(Context context, UUID clientViewUuid){
		return getViewUUID(context, clientViewUuid.getMostSignificantBits(), clientViewUuid.getLeastSignificantBits());
	}
	
	/**
	 * ViewInfo 의 기본정보를 설정하여 반환한다.
	 * @param context
	 * @param clientViewUuidMsb
	 * @param clientViewUuidLsb
	 * @return
	 */
	public static ViewInfo getViewInfo(Context context, long clientViewUuidMsb, long clientViewUuidLsb){
		String[] projection = new String[]{ ViewTable.KEY_VIEW_UUID_MSB, ViewTable.KEY_VIEW_UUID_LSB, 
				ViewTable.KEY_CHAT_TYPE, ViewTable.KEY_RECEIVER_UUID_MSB, ViewTable.KEY_RECEIVER_UUID_LSB };
		String select = "(" + ViewTable.KEY_CLIENT_VIEW_UUID_MSB + "=? AND "
		+ ViewTable.KEY_CLIENT_VIEW_UUID_LSB + "=?)";
		String[] selectionArgs = new String[]{ String.valueOf(clientViewUuidMsb), String.valueOf(clientViewUuidLsb)}; 
		ContentResolver cr = context.getContentResolver();
		Cursor viewCursor = cr.query(ViewTable.CONTENT_URI, 
				projection, 
				select,
				selectionArgs,
				null);
		ViewInfo viewInfo = new ViewInfo();
		if(viewCursor.moveToFirst()){
			viewInfo.setViewUuid(
					GpbSupport.makeUuidMsg(viewCursor.getLong(viewCursor.getColumnIndexOrThrow(ViewTable.KEY_VIEW_UUID_MSB)),
							viewCursor.getLong(viewCursor.getColumnIndexOrThrow(ViewTable.KEY_VIEW_UUID_LSB))));
			viewInfo.setType(
					viewCursor.getInt(viewCursor.getColumnIndexOrThrow(ViewTable.KEY_CHAT_TYPE)));
			viewInfo.setReceiverUuid(
					GpbSupport.makeUuidMsg(viewCursor.getLong(viewCursor.getColumnIndexOrThrow(ViewTable.KEY_RECEIVER_UUID_MSB)),
							viewCursor.getLong(viewCursor.getColumnIndexOrThrow(ViewTable.KEY_RECEIVER_UUID_LSB))));
		}
		viewCursor.close();
		return viewInfo;
	}
	
	public static ReceiverList getReceiverList(Context context, long clientViewUuidMsb, long clientViewUuidLsb){
		String[] projection = new String[]{ ViewTable.KEY_RECEIVER_LIST };
		String select = "(" + ViewTable.KEY_CLIENT_VIEW_UUID_MSB + "=? AND "
			+ ViewTable.KEY_CLIENT_VIEW_UUID_LSB + "=?)";
		String[] selectionArgs = new String[]{ String.valueOf(clientViewUuidMsb), String.valueOf(clientViewUuidLsb)}; 
		ContentResolver cr = context.getContentResolver();
		Cursor viewCursor = cr.query(ViewTable.CONTENT_URI, 
				projection, 
				select,
				selectionArgs,
				null);
		ReceiverList receiverList = new ReceiverList();
		if(viewCursor.moveToFirst() && viewCursor.getBlob(viewCursor.getColumnIndexOrThrow(ViewTable.KEY_RECEIVER_LIST)) != null){
			try {
				receiverList = ReceiverList.parseFrom(viewCursor.getBlob(viewCursor.getColumnIndexOrThrow(ViewTable.KEY_RECEIVER_LIST)));
			} catch (InvalidProtocolBufferMicroException e) {
				MTalkLogWriter.e(e);
			} catch (IllegalArgumentException e) {
				MTalkLogWriter.e(e);
			}
		}
		viewCursor.close();
		return receiverList;
	}
	
	public static int getChatType(Context context, long clientViewUuidMsb, long clientViewUuidLsb){
		String[] projection = new String[]{ ViewTable.KEY_CHAT_TYPE };
		String select = "(" + ViewTable.KEY_CLIENT_VIEW_UUID_MSB + "=? AND "
		+ ViewTable.KEY_CLIENT_VIEW_UUID_LSB + "=?)";
		String[] selectionArgs = new String[]{ String.valueOf(clientViewUuidMsb), String.valueOf(clientViewUuidLsb)}; 
		ContentResolver cr = context.getContentResolver();
		Cursor typeCursor = cr.query(ViewTable.CONTENT_URI, 
				projection, 
				select,
				selectionArgs,
				null);
		int chatType = -1;
		if(typeCursor.moveToFirst()){
			chatType = typeCursor.getInt(typeCursor.getColumnIndexOrThrow(ViewTable.KEY_CHAT_TYPE));
		}
		typeCursor.close();
		return chatType;
	}
	
	/**
	 * View의 멤버 카운트를 리턴한다.
	 * @param context
	 * @param clientViewUuid
	 * @return
	 */
	public static int getMembersCount(Context context, UUID clientViewUuid){
		String[] projection = new String[]{ViewTable.KEY_VIEW_MEMBER_COUNT};
		String select = "(" + ViewTable.KEY_CLIENT_VIEW_UUID_MSB + "=? AND "
		+ ViewTable.KEY_CLIENT_VIEW_UUID_LSB + "=?)";
		String[] selectionArgs = new String[]{ 
				String.valueOf(clientViewUuid.getMostSignificantBits()), 
				String.valueOf(clientViewUuid.getLeastSignificantBits())};
		ContentResolver cr = context.getContentResolver();
		Cursor memberCountCursor = cr.query(ViewTable.CONTENT_URI, 
				projection, 
				select, 
				selectionArgs, 
				null);
		int memberCount = -1;
		if(memberCountCursor.moveToFirst()){
			memberCount = memberCountCursor.getInt(memberCountCursor.getColumnIndexOrThrow(ViewTable.KEY_VIEW_MEMBER_COUNT));
		}
		memberCountCursor.close();
		return memberCount-1;
	}
	
	
	
	
	
	
	
	
	
	/** 업데이트 Update **/
	
	/**
	 * ViewInfo를 받아서 View를 업데이트.
	 * @param context
	 * @param viewInfo
	 */
	public static UUID updateView(Context context,
			ViewInfo viewInfo) {
		ContentValues cv = new ContentValues();
		if(viewInfo.getTitle()!=null){
			cv.put(ViewTable.KEY_TITLE, viewInfo.getTitle());
		}
		if(viewInfo.hasLatestMessage()){
			if(viewInfo.getLatestMessage().getType()==Common.MSG_TYPE_USER_MSG){
				cv.put(ViewTable.KEY_SUB_TITLE, viewInfo.getLatestMessage().getUserMassage().getContent());
			}
//			else if(viewInfo.getLatestMessage().getType()==Common.MSG_TYPE_SYSTEM_MSG){
//				cv.put(ViewTable.KEY_SUB_TITLE, "시스템 메시지"); // TODO : 시스템 메시지일때 표시 기준
//			}else if(viewInfo.getLatestMessage().getType()==Common.MSG_TYPE_CONTROL_MSG){
//				cv.put(ViewTable.KEY_SUB_TITLE, "컨트롤 메시지"); // TODO : 컨트롤 메시지일대 표시 기준
//			}else{
//				cv.put(ViewTable.KEY_SUB_TITLE, "알수 없는 메시지"); // TODO : 알수 없음
//			}
			cv.put(ViewTable.KEY_MESSAGE_LAST_TIME, TimeAdapter.getMillisecondFromUUID(GpbSupport.makeUuid(viewInfo.getLatestMessage().getMsgUuid())));
		}
		cv.put(ViewTable.KEY_VIEW_UNREAD_COUNT, viewInfo.getUnreadCount());
		cv.put(ViewTable.KEY_VIEW_MEMBER_COUNT, viewInfo.getMemberCount()); // TODO 테스트해볼것

		ContentResolver cr = context.getContentResolver();
		String where = ViewTable.KEY_VIEW_UUID_MSB+"=?" 
						+ " AND "
						+ ViewTable.KEY_VIEW_UUID_LSB+"=?";
		String[] selectionArgs = new String[]{ 
				String.valueOf(GpbSupport.msbOf(viewInfo.getViewUuid())), 
				String.valueOf(GpbSupport.lsbOf(viewInfo.getViewUuid()))}; 
		cr.update(
				ViewTable.CONTENT_URI, cv, 
				where, 
				selectionArgs);
		return InboxDatabaseHelper.getClientUUID(context, viewInfo.getViewUuid());
	}
	
	/**
	 * 새로운 UUID를 받아서 기존의 UUID 를 업데이트 한다.
	 * @param context
	 * @param clientViewUuid 기존의 UUID
	 * @param createViewUuid 업데이트할 UUID
	 */
	public static void updateViewUuid(Context context, UUID clientViewUuid, UUIDMsg createViewUuid){
		
		ContentValues cv = new ContentValues();
		cv.put(ViewTable.KEY_VIEW_UUID_MSB, GpbSupport.msbOf(createViewUuid));
		cv.put(ViewTable.KEY_VIEW_UUID_LSB, GpbSupport.lsbOf(createViewUuid));
		
		ContentResolver cr = context.getContentResolver();
		cr.update(ViewTable.CONTENT_URI, cv,
				ViewTable.KEY_CLIENT_VIEW_UUID_MSB+"=" 
				+ String.valueOf(clientViewUuid.getMostSignificantBits()) 
				+ " AND "
				+ ViewTable.KEY_CLIENT_VIEW_UUID_LSB+"=" 
				+ String.valueOf(clientViewUuid.getLeastSignificantBits()), null);
		
	}
	
	/**
	 * Push 상태를 업데이트 한다.
	 * @param viewUuid
	 * @param pushState
	 */
	public static void updateViewPushState(Context context, UUIDMsg viewUuid ,int pushState){
		ContentValues cv = new ContentValues();
		cv.put(ViewTable.KEY_VIEW_PUSH_ONOFF, pushState);
		ContentResolver cr = context.getContentResolver();
		
		cr.update(ViewTable.CONTENT_URI, cv,
				ViewTable.KEY_VIEW_UUID_MSB+"=" 
				+ String.valueOf(GpbSupport.msbOf(viewUuid)) 
				+ " AND "
				+ ViewTable.KEY_VIEW_UUID_LSB+"=" 
				+ String.valueOf(GpbSupport.lsbOf(viewUuid)), null);
	}
	
	public static void updateViewTitle(Context context, UUIDMsg viewUuid, String title){
		ContentValues cv = new ContentValues();
		cv.put(ViewTable.KEY_TITLE, title);
		ContentResolver cr = context.getContentResolver();
		
		cr.update(ViewTable.CONTENT_URI, cv,
				ViewTable.KEY_VIEW_UUID_MSB+"=" 
				+ String.valueOf(GpbSupport.msbOf(viewUuid)) 
				+ " AND "
				+ ViewTable.KEY_VIEW_UUID_LSB+"=" 
				+ String.valueOf(GpbSupport.lsbOf(viewUuid)), null);
	}
	
	/**
	 * 뷰의 생성 상태를  설정한다. (enable)
	 * @param context
	 * @param viewMsb
	 * @param viewLsb
	 */
	public static void updateViewEnable(Context context, long clientViewUuidMsb, long clientViewUuidLsb, int enable){
		ContentResolver cr = context.getContentResolver();
		String where = ViewTable.KEY_CLIENT_VIEW_UUID_MSB+"=" 
		+ String.valueOf(clientViewUuidMsb) 
		+ " AND "
		+ ViewTable.KEY_CLIENT_VIEW_UUID_LSB+"=" 
		+ String.valueOf(clientViewUuidLsb);
		Cursor cursor = cr.query(ViewTable.CONTENT_URI, new String[]{ViewTable.KEY_VIEW_ENABLE}, where, null, null);
		if(cursor.moveToFirst()){
			ContentValues cv = new ContentValues();
			cv.put(ViewTable.KEY_VIEW_ENABLE, enable);
			cr.update(ViewTable.CONTENT_URI, cv, 
					where, null);
		}
		cursor.close();
	}
	
	/**
	 * Member 리스트를 저장한다.
	 * @param context
	 * @param clientViewUuidMsb
	 * @param clientViewUuidLsb
	 * @param memberList
	 */
	public static void setMemberList(Context context, long clientViewUuidMsb, long clientViewUuidLsb, ReceiverList memberList){
		ContentResolver cr = context.getContentResolver();

		String where = ViewTable.KEY_CLIENT_VIEW_UUID_MSB+"=" 
			+ String.valueOf(clientViewUuidMsb) 
			+ " AND "
			+ ViewTable.KEY_CLIENT_VIEW_UUID_LSB+"=" 
			+ String.valueOf(clientViewUuidLsb);
		
		ContentValues cv = new ContentValues();
		cv.put(ViewTable.KEY_RECEIVER_LIST, memberList.toByteArray());
		cr.update(ViewTable.CONTENT_URI, cv, where, null);
	}
	
	
	
	
	
	
	
	
	
	
	
	/** 삭제 Delete**/
	
	/**
	 * 뷰가 Disable 일때 삭제
	 */
	public static void disableViewDelete(Context context, long clientViewUuidMsb, long clientViewUuidLsb){
		ContentResolver cr = context.getContentResolver();
		cr.delete(ViewTable.CONTENT_URI, 
				ViewTable.KEY_CLIENT_VIEW_UUID_MSB+"=" 
				+ String.valueOf(clientViewUuidMsb) 
				+ " AND "
				+ ViewTable.KEY_CLIENT_VIEW_UUID_LSB+"=" 
				+ String.valueOf(clientViewUuidLsb)
				+ " AND "
				+ ViewTable.KEY_VIEW_ENABLE+"="
				+ ViewTable.EnableType.DISABLE.ordinal(), null);
	}
	
	/**
	 * ViewUUID에 대한 뷰를 삭제한다.
	 * @param context
	 * @param viewUuid
	 */
	public static void deleteView(Context context, UUIDMsg viewUuid) {
		deleteView(context, GpbSupport.msbOf(viewUuid), GpbSupport.lsbOf(viewUuid));
	}
	
	public static void deleteView(Context context, long viewUuidMsg, long viewUuidLsb){
		ContentResolver cr = context.getContentResolver();
		cr.delete(ViewTable.CONTENT_URI,
				ViewTable.KEY_VIEW_UUID_MSB+"=" 
				+ String.valueOf(viewUuidMsg) 
				+ " AND "
				+ ViewTable.KEY_VIEW_UUID_LSB+"=" 
				+ String.valueOf(viewUuidLsb), null);
	}
	
	/**
	 * 뷰 테이블을 내용을 전부 삭제한다.
	 */
	public static void deleteAllView(Context context)
	{
		ContentResolver cr = context.getContentResolver();
		cr.delete(ViewTable.CONTENT_URI, null, null);
	}
	
	
	
	
	/** 추가 내용 **/
	
	/**
	 * ViewInfo 를 이용하여 데이터베이스에 사용할 ContentValues를 만든다.
	 * @param viewInfo
	 * @return
	 */
	public static ContentValues setViewContentValues(ViewInfo viewInfo){
		ContentValues cv = new ContentValues();
		if(viewInfo.getTitle()!=null){
			cv.put(ViewTable.KEY_TITLE, viewInfo.getTitle());
		} else {
			cv.put(ViewTable.KEY_TITLE, "MAKING!!!!"); // TODO : 이거는 따로 만들어야 하고
		}
		if(viewInfo.getLatestMessage()!=null){
			if(viewInfo.getLatestMessage().getType()==Common.MSG_TYPE_USER_MSG){
				cv.put(ViewTable.KEY_SUB_TITLE, viewInfo.getLatestMessage().getUserMassage().getContent());
			}
			cv.put(ViewTable.KEY_MESSAGE_LAST_TIME, TimeAdapter.getMillisecondFromUUID(GpbSupport.makeUuid(viewInfo.getLatestMessage().getMsgUuid())));
		}
		cv.put(ViewTable.KEY_VIEW_UNREAD_COUNT, viewInfo.getUnreadCount());
		cv.put(ViewTable.KEY_VIEW_MEMBER_COUNT, viewInfo.getMemberCount()); // TODO 테스트해볼것
		return cv;
	}
	
	public static Cursor getViewCursor(Context context)
	{
		ContentResolver cr = context.getContentResolver();
		Cursor c = cr.query(ViewTable.CONTENT_URI, null, null, null, null);
		if(c == null || c.getCount() < 1)
			return null;
		else
		{
			c.moveToFirst();
			return c;
		}
	}
}
